package main

import (
	"fmt"
	"math"
)

var (
	totalNum     = 8000
	totalRoutine = 4
	intChan      = make(chan int, 1000)
	primeChan    = make(chan int, 2000)
	exitChan     = make(chan bool, 4)
)

func main() {
	go putNum()

	for i := 0; i < totalRoutine; i++ {
		go putPrime()
	}

	// 使用另一个协程关闭管道
	go func() {
		for i := 0; i < totalRoutine; i++ {
			<-exitChan
		}

		close(primeChan)
	}()

	for {
		res, ok := <-primeChan
		if !ok {
			break
		}
		fmt.Printf("prime=%d\n", res)
	}
	fmt.Println("main exit0")
}

func putNum() {
	for i := 1; i <= totalNum; i++ {
		intChan <- i
	}
	close(intChan)
}

func putPrime() {
	var num int
	var ok bool
	for {
		num, ok = <-intChan
		if !ok {
			break
		}
		if checkPrime(num) {
			primeChan <- num
		}
	}
	// 这里不可以关闭,因为不知道其他协程是否完成
	// 所以仅添加true
	exitChan <- true
}

func checkPrime(num int) bool {
	for i := 2; float64(i) < math.Sqrt(float64(num)); i++ {
		if num%i == 0 {
			return false
		}
	}
	return true
}
